﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsApplication2._910_网络._09.test
{
    public partial class Form1 : Form
    {
        System.Net.Sockets.Socket client;
        private delegate void NoticeTextEventHandler(System.String sReceived);
        private event NoticeTextEventHandler NoticeTextEvent;

        private static ManualResetEvent sendDone =
           new ManualResetEvent(false);

        public Form1()
        {
            InitializeComponent();

            this.NoticeTextEvent += new NoticeTextEventHandler(this.ShowBufferNotice);
        }

        private void ShowBufferNotice(string strReiceve)
        {
            //this.richTextBox2.Text += strReiceve;
            this.richTextBoxNoticeReturn.Text += strReiceve;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Connect();
        }

        private void Connect()
        {
            string ip = this.textBoxIP.Text;
            string port = this.textBoxPort.Text;

            if (ip == "")
            {
                MessageBox.Show("填写 ip");
                return;
            }
            if (port == "")
            {
                MessageBox.Show("填写 port");
                return;
            }

            int intPort;
            intPort = Convert.ToInt32(port);

            ConnectServer(ip, intPort);
        }

        private void ConnectServer(string strIP, int nPort)
        {
            IPEndPoint ipServer;

            //strIP = "www.sohu.com";

            strIP = Dns.GetHostAddresses(strIP)[0].ToString();

            IPAddress svrIP = IPAddress.Parse(strIP);
            ipServer = new IPEndPoint(svrIP, nPort);

            this.client = new System.Net.Sockets.Socket(
                System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream,
                System.Net.Sockets.ProtocolType.Tcp);

            this.client.Blocking = false;

            this.client.BeginConnect(ipServer, new System.AsyncCallback(ConnectCallback), client);
        }

        private void ConnectCallback(System.IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;

                client.EndConnect(ar);

                MessageBox.Show("连接成功");

                Receive(client);
            }

            catch (System.Exception CurException)
            {
                MessageBox.Show(CurException.Message);

                client = null;
            }
        }

        private void Receive(Socket client)
        {
            try
            {
                StateObject state = new StateObject();
                state.workSocket = client;

                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, System.Net.Sockets.SocketFlags.None,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public class StateObject
        {
            // Client socket.
            public Socket workSocket = null;
            // Size of receive buffer.
            public const int BufferSize = 2048;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();

            public void ClearBuffer()
            {
                this.buffer = new byte[BufferSize];
            }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                int bytesRead = client.EndReceive(ar);
                if (bytesRead > 0)
                {
                    //*********************************************************
                    //全局返回
                    //*********************************************************
                    string sReceived = "";

                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    if (state.sb.Length > 1)
                    {
                        sReceived = state.sb.ToString();
                    }

                    this.Invoke(this.NoticeTextEvent, sReceived);

                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            string strSend = this.richTextBoxSend.Text;

            //strSend = "GET  /   HTTP/1.0 \r\n Host:   www.sohu.com \r\n";
            if (strSend == "")
            {
                MessageBox.Show(" 输入命令 ");
                return;
            }

            strSend = strSend + "\r\r";

            sendDone.Reset();
            Send(client, strSend);
            sendDone.WaitOne();
        }

        private static void Send(Socket client, String data)
        {
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;

                int bytesSent = client.EndSend(ar);

                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.richTextBoxSend.Text = "GET  /   HTTP/1.0 \r\n Host:   www.sohu.com \r\n";
        }
    }
}